package com.example.deepschool.Controller.User;

import com.example.deepschool.Model.Response.ApiResponse;
import com.example.deepschool.Model.Response.ResponseData;
import com.example.deepschool.Model.User;
import com.example.deepschool.enums.GlobalVariables_String;
import com.example.deepschool.service.composite.CompositeService;
import com.example.deepschool.util.Redis;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.core.io.support.ResourceRegion;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 用户控制器，负责处理所有与用户相关的请求。
 * 包括用户注册、登录、信息更新、头像上传/获取、密码修改和注销等功能。
 */
@Tag(name = "用户API")
@RestController("User")
@RequestMapping("/User")
public class Controller {
	
	// 用户令牌的全局变量
	private final String TOKEN = GlobalVariables_String.TOKEN.getValue();
	
	/**
	 * 用户控制器的构造函数。
	 */
	public Controller () {
	}
	
	
	/**
	 * 用户注册。
	 *
	 * @param user 待注册的用户信息。
	 * @return 注册结果的API响应。
	 */
	@Operation(summary = "注册")
	@PostMapping("/register")
	public ResponseEntity<Object> register (@Validated @RequestBody User user) {
		CompositeService.user.register(user);
		return ApiResponse.GetApiResponse()
				       .ok()
				       .body("注册成功")
				       .build();
	}
	
	/**
	 * 通过用户名登录。
	 *
	 * @param user 包含用户名和密码的用户信息。
	 * @return 登录结果的API响应，包括用户信息和令牌。
	 */
	@Operation(summary = "登录_用户名",
	           description = "根据用户名登录")
	@PostMapping("/login_username")
	public ResponseEntity<Object> login_username (@RequestBody User user) {
		
		user = CompositeService.user.login_username(user);
		Map<String, Object> map = new HashMap<>();
		map.put("data", user);
		String token = Redis.HGET(user.getUsername(), "UUID");
		return ApiResponse.GetApiResponse()
				       .ok()
				       .addHeader(TOKEN, token)
				       .body(map)
				       .build();
	}
	
	/**
	 * 通过邮箱登录。
	 *
	 * @param user 包含邮箱和密码的用户信息。
	 * @return 登录结果的API响应，包括用户信息和令牌。
	 */
	@Operation(summary = "登录_邮箱",
	           description = "根据邮箱登录")
	@PostMapping("/login_email")
	public ResponseEntity<Object> login_email (@RequestBody User user) {
		
		user = CompositeService.user.login_email(user);
		Map<String, Object> map = new HashMap<>();
		map.put("data", user);
		String token = Redis.HGET(user.getUsername(), "UUID");
		return ApiResponse.GetApiResponse()
				       .ok()
				       .addHeader(TOKEN, token)
				       .body(map)
				       .build();
	}
	
	/**
	 * 更新用户信息。
	 *
	 * @param user    新的用户信息。
	 * @param request 包含用户令牌的HTTP请求。
	 * @return 更新结果的API响应。
	 */
	@Operation(summary = "修改信息",
	           description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
	@PostMapping("/updateUser")
	public ResponseEntity<Object> updateUser (@RequestBody User user, HttpServletRequest request) {
		Map<String, Object> map = new HashMap<>();
		user = CompositeService.user.updateUser(user, request.getHeader(TOKEN));
		map.put("data", user);
		return ApiResponse.GetApiResponse()
				       .ok()
				       .body(map)
				       .build();
	}
	
	/**
	 * 上传用户头像。
	 *
	 * @param Avatar     用户上传的头像文件。
	 * @param fileSHA256 头像文件的SHA256校验码。
	 * @param request    包含用户令牌的HTTP请求。
	 * @return 更新后的用户信息的API响应。
	 */
	@Operation(summary = "上传头像",
	           description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
	@PostMapping("/putAvatar")
	public ResponseEntity<Object> putAvatar (@RequestParam MultipartFile Avatar,
	                                         @RequestParam String fileSHA256,
	                                         HttpServletRequest request) {
		
		User user = CompositeService.user.putAvatar(Avatar, fileSHA256, request.getHeader(TOKEN));
		Map<String, Object> map = new HashMap<>();
		map.put("data", user);
		return ApiResponse.GetApiResponse()
				       .ok()
				       .body(map)
				       .build();
	}
	
	/**
	 * 获取用户头像。
	 *
	 * @param Avatar 头像的标识。
	 * @return 头像文件的API响应。
	 */
	@Operation(summary = "获取头像")
	@GetMapping("/Not_verified/getAvatar")
	public ResponseEntity<ResourceRegion> getAvatar (@RequestParam String Avatar, HttpServletRequest request) {
		String Range = request.getHeader(HttpHeaders.RANGE);
		ResponseData responseData = CompositeService.user.getAvatar(Avatar, Range);
		return ApiResponse.GetApiResponse()
				       .binBody(responseData)
				       .onlineBuild();
	}
	
	
	/**
	 * 修改用户密码。
	 *
	 * @param oldPassword  用户当前密码。
	 * @param newPassword  用户新密码。
	 * @param newPassword2 新密码的确认。
	 * @param request      包含用户令牌的HTTP请求。
	 * @return 修改密码结果的API响应。
	 */
	@Operation(summary = "修改密码",
	           description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
	@PostMapping("/updatePassword")
	public ResponseEntity<Object> updatePassword (@RequestParam String oldPassword,
	                                              @RequestParam String newPassword,
	                                              @RequestParam String newPassword2,
	                                              HttpServletRequest request) {
		CompositeService.user.updatePassword(oldPassword, newPassword, newPassword2, request.getHeader(TOKEN));
		Map<String, Object> map = new HashMap<>();
		map.put("msg", "密码修改成功");
		return ApiResponse.GetApiResponse()
				       .ok()
				       .body(map)
				       .build();
	}
	
	/**
	 * 用户注销。
	 *
	 * @param request 包含用户令牌的HTTP请求。
	 * @return 注销结果的API响应。
	 */
	@Operation(summary = "注销",
	           description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
	@DeleteMapping("/logout")
	public ResponseEntity<Object> logout (HttpServletRequest request) {
		String UUID = request.getHeader(TOKEN);
		CompositeService.user.logout(UUID);
		Map<String, Object> map = new HashMap<>();
		map.put("msg", "已注销！");
		return ApiResponse.GetApiResponse()
				       .ok()
				       .body(map)
				       .build();
	}
}
